package net.tyw.common.utils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class DateUtil {
    /**
     * 完整时间 yyyy-MM-dd HH:mm:ss
     */
    public static final String SIMPLE_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
    private final static long MILLISECONDS_EVERY_DAY = 24L * 3600 * 1000;

    private DateUtil() {
    }

    /**
     * <p>
     * 当前日期时间
     * </p>
     *
     * @return
     */
    public static Date current() {
        return new Date();
    }

    /**
     * <p>
     * 判断指定日期是否在有效期之内。
     * </p>
     * <p>
     * <p>
     * 若指定时间是：2011-06-01 09:12:00，有期效为 10 天。当前时间在 2011-06-11 09:12:00
     * 之后则表示已经不在有效期内。
     * </p>
     *
     * @param date   指定时间
     * @param period 有效期（天）
     * @return
     */
    public static boolean isIndate(Date date, int period) {
        return date.getTime() + MILLISECONDS_EVERY_DAY * period <= System.currentTimeMillis();
    }

    /**
     * <p>
     * 将 Date 中的时、分、秒、毫秒清零
     * </p>
     *
     * @param date
     * @return
     */
    public static Date clearTime(Date date) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date changeSecond(int changeSecond) {
        Date date = new Date();
        return changeSecond(date, changeSecond);
    }

    public static Date changeSecond(Date date, int change) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.SECOND, change);
        return c.getTime();
    }

    /**
     * <p>
     * 在日期基础上做基于分钟的加和减，并且将时、分、秒、毫秒清零
     * </p>
     *
     * @param changeMinutes 变化的分钟数（负数表示减少，正数表示增加）
     * @return
     */
    public static Date changeMinute(int changeMinutes) {
        Date date = new Date();
        return changeMinute(date, changeMinutes);
    }

    public static Date changeMinute(Date date, int change) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, change);
        return c.getTime();
    }


    public static Date changeHour(int changeHours) {
        Date date = new Date();
        return changeHour(date, changeHours);
    }

    public static Date changeHour(Date date, int change) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.HOUR, change);
        return c.getTime();
    }

    /**
     * <p>
     * 在日期基础上做基于日的加和减，并且将时、分、秒、毫秒清零
     * </p>
     *
     * @param changeDays 变化的天数（负数表示减少，正数表示增加）
     * @return
     */
    public static Date changeDay(int changeDays) {
        Date date = new Date();
        return changeDay(date, changeDays);
    }

    public static Date changeDay(Date date, int change) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DAY_OF_MONTH, change);
        return c.getTime();
    }

    /**
     * <p>
     * 在日期基础上做基于日的加和减，并且将时、分、秒、毫秒清零
     * </p>
     *
     * @param changeMonth 变化的月数（负数表示减少，正数表示增加）
     * @return
     */
    public static Date changeMonth(int changeMonth) {
        Date date = new Date();
        return changeMonth(date, changeMonth);
    }

    public static Date changeMonth(Date date, int change) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MONTH, change);
        return c.getTime();
    }

    /**
     * 获取系统当前日期(精确到毫秒)，格式：yyyy-MM-dd HH:mm:ss
     *
     * @return
     */
    public static String getDateFormatter() {
        Date date = new Date();
        DateFormat df = new SimpleDateFormat(SIMPLE_DATE_FORMAT);
        return df.format(date);
    }

    /**
     * <p>
     * 以 datetime 格式化日期
     * </p>
     *
     * @param date
     * @return
     */
    public static String formatDatetime(Date date) {
        if (date == null) {
            return null;
        }
        return format("yyyy-MM-dd HH:mm:ss", date);
    }

    /**
     * <p>
     * 以 datetime 格式化日期
     * </p>
     *
     * @param date
     * @return
     */
    public static String formatDatetimes(Date date) {
        if (date == null) {
            return null;
        }
        return format("HHmmssyyyyMMdd ", date);
    }

    /**
     * <p>
     * 以 date 格式化日期
     * </p>
     *
     * @param date
     * @return
     */
    public static String formatDate(Date date) {
        if (date == null) {
            return null;
        }
        return format("yyyyMMdd", date);
    }

    /**
     * 计算两个日期之间相差的天数
     *
     * @param startDate
     * @param endDate
     * @return
     */

    public static int subDays(Date startDate, Date endDate) {
        Calendar calendar = Calendar.getInstance();

        calendar.setTime(startDate);

        int start = calendar.get(Calendar.DAY_OF_YEAR);

        calendar.setTime(endDate);

        int end = calendar.get(Calendar.DAY_OF_YEAR);

        return start - end;
    }

    public static String format(String pattern, Date date) {
        return new SimpleDateFormat(pattern).format(date);
    }

    public static String format(String pattern) {
        return new SimpleDateFormat(pattern).format(current());
    }

    public static Date parse(String pattern, String strDateTime) {
        Date date = null;
        if (strDateTime == null || pattern == null) {
            return null;
        }
        try {
            SimpleDateFormat formatter = new SimpleDateFormat(pattern);
            formatter.setLenient(false);
            date = formatter.parse(strDateTime);
        } catch (ParseException e) {
            return null;
        }
        return date;
    }

    public static String getYearAnimalName() {
        return getYearAnimalName(null);
    }

    public static String getYearAnimalName(Date date) {
        if (date == null) {
            date = current();
        }
        int year = Integer.parseInt(format("YYYY", date));
        int jiaziYear = 1804;
        if (year < jiaziYear) {// 如果年份小于起始的甲子年(startYear = 1804),则起始甲子年往前偏移
            jiaziYear = jiaziYear - (60 + 60 * ((jiaziYear - year) / 60));// 60年一个周期
        }
        year = year - jiaziYear;
        String[] animalYear = new String[]{"鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"};
        String name = animalYear[year % 12];
        return name;
    }


    /**
     * 判断原日期是否在目标日期之后
     *
     * @param src
     * @param dst
     * @return
     */
    public static boolean isAfter(Date src, Date dst) {
        return src.after(dst);
    }

    /**
     * 判断原日期是否在目标日期之前
     *
     * @param src
     * @param dst
     * @return
     */
    public static boolean isBefore(Date src, Date dst) {
        return src.before(dst);
    }

    public static boolean isAfterNow(Date date) {
        Date now = current();
        return date.after(now);
    }

    /**
     * 获取当天的开始时间
     *
     * @return
     */
    public static Date getBeginDayOfToday() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取当天的结束时间
     *
     * @return
     */
    public static Date getEndDayOfToday() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime();
    }

    /**
     * 获取昨天的开始时间
     *
     * @return
     */
    public static Date getBeginDayOfYesterday() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getBeginDayOfToday());
        cal.add(Calendar.DAY_OF_MONTH, -1);
        return cal.getTime();
    }

    /**
     * 获取昨天的结束时间
     *
     * @return
     */
    public static Date getEndDayOfYesterDay() {
        Calendar cal = new GregorianCalendar();
        cal.setTime(getEndDayOfToday());
        cal.add(Calendar.DAY_OF_MONTH, -1);
        return cal.getTime();
    }

    /**
     * 获取本周的开始时间
     *
     * @return
     */
    public static Date getBeginDayOfCurrentWeek() {
        Date date = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);
        return cal.getTime();
    }

    /**
     * 获取本周的结束时间
     *
     * @return
     */
    public static Date getEndDayOfCurrentWeek() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getBeginDayOfCurrentWeek());
        cal.add(Calendar.DAY_OF_WEEK, 6);
        return cal.getTime();
    }

    /**
     * 获取本周的开始时间
     *
     * @return
     */
    public static Date getBeginDayOfLastWeek() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getBeginDayOfCurrentWeek());
        cal.add(Calendar.DAY_OF_WEEK, -7);
        return cal.getTime();
    }


    /**
     * 获取本周的结束时间
     *
     * @return
     */
    public static Date getEndDayOfLastWeek() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getEndDayOfCurrentWeek());
        cal.add(Calendar.DAY_OF_WEEK, -7);
        return cal.getTime();
    }

    /**
     * 获取本月的开始时间
     *
     * @return
     */
    public static Date getBeginDayOfCurrentMonth() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DATE, cal.getActualMinimum(Calendar.DATE));
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取本月的结束时间
     *
     * @return
     */
    public static Date getEndDayOfCurrentMonth() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        return cal.getTime();
    }

    /**
     * 获取上月的开始时间
     *
     * @return
     */
    public static Date getBeginDayOfLastMonth() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, -1);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取上月的结束时间
     *
     * @return
     */
    public static Date getEndDayOfLastMonth() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_MONTH, 0);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        return cal.getTime();
    }


}
